package com.ebrg.secure9.activity.setup;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextWatcher;
import android.text.util.Rfc822Tokenizer;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.MultiAutoCompleteTextView;
import android.widget.Toast;
import android.widget.AutoCompleteTextView.Validator;

import com.ebrg.secure9.Account;
import com.ebrg.secure9.EmailAddressAdapter;
import com.ebrg.secure9.EmailAddressValidator;
import com.ebrg.secure9.Preferences;
import com.ebrg.secure9.R;
import com.ebrg.secure9.activity.K9Activity;
import com.ebrg.secure9.activity.MessageCompose;
import com.ebrg.secure9.activity.MessageList;
import com.ebrg.secure9.mail.Address;
import com.ebrg.secure9.mail.MessagingException;
import com.ebrg.secure9.mail.security.DiffieHellman;
import com.ebrg.secure9.mail.security.Keys;

public class EncryptionNewKey extends K9Activity implements OnClickListener{
	private Account mAccount;
	private static final String EXTRA_ACCOUNT = "account";
	private EditText localEmail;
	private MultiAutoCompleteTextView remoteEmail;
	private Button createKeyButton;
	public static String remoteEmailSource;
	public static Address[] otherParty;
	public static String calledBy;
	private EmailAddressAdapter mAddressAdapter;
	private Validator mAddressValidator;

	public static void actionNewKey(Activity context, Account account, String originator, String recipient)
	{
		Intent i = new Intent(context, EncryptionNewKey.class);
		i.setAction(Intent.ACTION_EDIT);
		i.putExtra("account", account.getUuid());
		calledBy = originator; 
		remoteEmailSource = recipient;
		context.startActivity(i);
	}


 //Create key
	private void onNext() throws MessagingException
	{
		String FILENAME = (localEmail.getText().toString()  + 
				remoteEmail.getText().toString() + EncryptionNewKey.this.getString(R.string.initial_key_file_type).toLowerCase());

		if(Keys.keyExists(this, localEmail.getText().toString(),remoteEmail.getText().toString()))
		{
			Toast.makeText(EncryptionNewKey.this, "Duplicate key already exists", Toast.LENGTH_LONG).show();
			MessageList.actionHandleFolder(this, mAccount, mAccount.getAutoExpandFolderName());
		}
		
		else if(remoteEmail.getText().toString().length() < 5 || !remoteEmail.getText().toString().contains("@") ||
				!remoteEmail.getText().toString().contains("."))
			Toast.makeText(EncryptionNewKey.this, "Invalid remote email address", Toast.LENGTH_LONG).show();
		
		else
		{
			//Send diffie setup email unless user is generating key off received email (last step)
			if(!calledBy.equals("receive"))
			{
				otherParty = MessageCompose.getAddressFromString(remoteEmail.getText().toString());
				DiffieHellman dh = DiffieHellman.getDefault();
				try 
				{
					FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
					fos.write((remoteEmail.getText().toString() + "\n" + localEmail.getText().toString() + "\nOO").getBytes());
					fos.write((dh.getModulus() + "OO").getBytes());
					fos.write((dh.getGenerator() + "OO").getBytes());
					fos.write((dh.getPublicKey() + "OO").getBytes());
					fos.write((dh.getPrivateKey() + "OO").getBytes());
					fos.close();

				} 
				catch (FileNotFoundException e) 
				{
					Toast.makeText(EncryptionNewKey.this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
				} 
				catch (IOException e) 
				{
					Toast.makeText(EncryptionNewKey.this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
				}

				MessageCompose.sendDHKey(this, otherParty, mAccount, dh);
				Toast.makeText(EncryptionNewKey.this, "Diffie-Hellman initiator sent", Toast.LENGTH_SHORT).show();

				if(calledBy.equals("settings"))
					EncryptionSettings.encryptionSettings(this, mAccount);
				else
					MessageList.actionHandleFolder(this, mAccount, mAccount.getAutoExpandFolderName());

			}
			//Alert user that process is completed, then return to settings page.
			Toast.makeText(EncryptionNewKey.this, "You will receive a key response from the recipient, at which point you may finish key setup and this key will become usable.", Toast.LENGTH_LONG).show();
			Toast.makeText(EncryptionNewKey.this, "You will receive a key response from the recipient, at which point you may finish key setup and this key will become usable.", Toast.LENGTH_LONG).show();

			calledBy = "";
			finish();
		}



	}

	public EncryptionNewKey(){}

	//Final step when remote user replies with their public key
	public  void writeKeyReceived(String me, String sender, String publicKey, String privateKey, String sharedKey)
	{
		String FILENAME = (me + sender + this.getString(R.string.complete_key_file_type)).toLowerCase();
		try 
		{			
			FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
			fos.write(sender.getBytes());
			fos.write("\n".getBytes());
			fos.write(me.getBytes());
			fos.write("\n".getBytes());			
			fos.write("OO".getBytes());
			fos.write((privateKey + "OO").getBytes());
			fos.write((publicKey + "OO").getBytes());
			fos.write((sharedKey + "OO").getBytes());
			fos.close();
			Keys.keyList.add((me + sender + this.getString(R.string.complete_key_file_type)).toLowerCase());

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			Log.v("Fie not found", e.getLocalizedMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Log.v("IO Exception",e.getLocalizedMessage());

		}
	}
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		
		String accountUuid = getIntent().getStringExtra("account");
		mAccount = Preferences.getPreferences(this).getAccount(accountUuid);

		setContentView(R.layout.encryption_new_key);
		this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 

		if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_ACCOUNT))
		{
			accountUuid = savedInstanceState.getString(EXTRA_ACCOUNT);
			mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
		}

		
		TextWatcher watcher = new TextWatcher()
		{
			public void beforeTextChanged(CharSequence s, int start,
					int before, int after) { }

			public void onTextChanged(CharSequence s, int start,
					int before, int count)
			{
				if(s.toString().contains("<") && s.toString().contains(">") && s.toString().contains(",")){
					String fullEmail = s.toString();
					String trimmed;
					trimmed = fullEmail.substring(fullEmail.indexOf("<") + 1, fullEmail.lastIndexOf(">"));
					remoteEmail.setText(trimmed);
				}

			}

			public void afterTextChanged(android.text.Editable s) { }
		};

		
		
		remoteEmail = (MultiAutoCompleteTextView)findViewById(R.id.remote_email);
		//Set remote email textbox with remote email (if coming from message Compose)
		remoteEmail.setText(remoteEmailSource);
		remoteEmail.addTextChangedListener(watcher);
		mAddressAdapter = EmailAddressAdapter.getInstance(this);
		mAddressValidator = new EmailAddressValidator();
		remoteEmail.setAdapter(mAddressAdapter);
		remoteEmail.setTokenizer(new Rfc822Tokenizer());
		remoteEmail.setValidator(mAddressValidator);
		
		
		
		//Set local email to account email and disable text field
		localEmail = (EditText)findViewById(R.id.local_email);
		localEmail.setText(mAccount.getEmail());
		localEmail.setEnabled(false);
		localEmail.setFocusable(false);

		//Enable create key button, clear out remoteEmailSource for next use.
		createKeyButton = (Button)findViewById(R.id.create_key);
		createKeyButton.setOnClickListener(this);
		createKeyButton.setEnabled(true);
		remoteEmailSource = null;
	}

	@Override
	public void onResume()
	{
		super.onResume();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public void onSaveInstanceState(Bundle outState)
	{
		super.onSaveInstanceState(outState);
		outState.putSerializable(EXTRA_ACCOUNT, mAccount.getUuid());
	}

	public void onClick(View v)
	{
		switch (v.getId())
		{
		case R.id.create_key:
			try {
				onNext();
			} catch (MessagingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			break;
		}
	}
}
